package com.book.filter;

import com.alibaba.fastjson.JSON;
import com.book.domain.LoginUser;
import com.book.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

//过滤器
@Component
public class UserIdAuthenticationFilte extends OncePerRequestFilter {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取userId或者userIdAdmin
        String userId = request.getHeader("userId");
        String userIdAdmin = request.getHeader("userIdAdmin");

//        System.out.println(userId+"::::"+userIdAdmin);

        //为null判断，如果为Null,说明是登录注册等不需要id的接口，就放行让他去登陆或注册或其他操作
        //登录注册时不存在userId或者userIdAdmin信息就放行，如果都不存在就说明用户或管理员未登录。

        if(!StringUtils.hasText(userId) && !StringUtils.hasText(userIdAdmin)){
            filterChain.doFilter(request,response);
            return ;
        }

//        System.out.println(request.getRequestURL());
        if((request.getRequestURL().toString()).equals("http://127.0.0.1:8088/getCaptcha")){//如果是已经登录且又发送邮箱就不认证
            filterChain.doFilter(request,response);
            return;
        }
        String userid;//注意这里跟上面的区别，这里全部是小写，为了后面统一做的操作
        //解析userId或者userIdAdmin,如果是管理员发送的请求会带后者不带前者，因此前者为null,就算浏览器上两个都存在也是一样
        try {
            if(StringUtils.hasText(userId)){
                userid = userId;
            }else userid = userIdAdmin;
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("用户id非法1,请删除浏览器缓存");
        }

        //从redis中获取用户信息
        String redisKey = "login:"+userid;

        //高版本的jdk不可以用redisCache反序列化,不然会报错!建议使用stringRedisTemplate+Json进行反序列化,下面两行是替代方法
//        LoginUser loginUser = redisCache.getCacheObject(redisKey);
        String redis= stringRedisTemplate.opsForValue().get(redisKey);
        LoginUser loginUser = JSON.parseObject(redis, LoginUser.class);


        if(Objects.isNull(loginUser)){
            throw new RuntimeException("用户登陆状态过期1");
        }
        //存入SecurityContextHolder
        //这里必须用3个参数，LoginServiceImpl中是两个，因为我们要把这里改为已认证的状态，因为本方法本身就是在做认证而且认证正确了

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(loginUser,null, null);


        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        //token存在且上述操作完成就放行继续访问下一个过滤器或者访问目标资源
        filterChain.doFilter(request,response);
    }
}
